package com.gitee.wsl.mathematics.geometry.d2.rect.ext


import com.gitee.wsl.mathematics.geometry.d2.rect.Rectangle
import com.gitee.wsl.mathematics.vector.vec2.Vec2f
import com.gitee.wsl.mathematics.vector.vec2.Vector2
import kotlin.jvm.JvmName
import kotlin.math.max
import kotlin.math.min

fun Iterable<Rectangle>.bounds(): Rectangle {
    var first = true
    var left = 0.0f
    var right = 0.0f
    var top = 0.0f
    var bottom = 0.0f
    for (r in this) {
        if (first) {
            left = r.left
            right = r.right
            top = r.top
            bottom = r.bottom
            first = false
        } else {
            left = min(left, r.left)
            right = max(right, r.right)
            top = min(top, r.top)
            bottom = max(bottom, r.bottom)
        }
    }
    return Rectangle(left, top, right, bottom)
}

/** Calculates [Rectangle]-bounds for a list of [Rectangle] instances. */
val List<Rectangle>.bounds: Rectangle
    @JvmName("getRectangleBounds") get() {
        var minX = Double.POSITIVE_INFINITY
        var minY = Double.POSITIVE_INFINITY
        var maxX = Double.NEGATIVE_INFINITY
        var maxY = Double.NEGATIVE_INFINITY

        this.forEach {
            if (it != Rectangle.EMPTY) {
                minX = min(minX, it.left.toDouble())
                maxX = max(maxX, it.left.toDouble() + it.width)
                minY = min(minY, it.top.toDouble())
                maxY = max(maxY, it.top.toDouble() + it.height)
            }
        }
        return Rectangle(Vec2f(minX, minY), maxX - minX, maxY - minY)
    }


/**
 * Calculates [Rectangle]-bounds from a [List] of [Vector2] instances.
 *
 * The provided list should consist of more than one item for optimal results.
 */
val List<Vec2f>.bounds: Rectangle
    get() {
        var minX = Float.POSITIVE_INFINITY
        var minY = Float.POSITIVE_INFINITY
        var maxX = Float.NEGATIVE_INFINITY
        var maxY = Float.NEGATIVE_INFINITY

        this.forEach {
            minX = min(minX, it.x)
            maxX = max(maxX, it.x)
            minY = min(minY, it.y)
            maxY = max(maxY, it.y)
        }
        return Rectangle(Vec2f(minX, minY), Vec2f(maxX , maxY))
    }


